from django.db import models
import uuid
import re
# Create your models here.
"""
Django 数据库迁移命令: 
python manage.py makemigrations
python manage.py migrate
"""

# 用户
class Users(models.Model):
    username = models.CharField(max_length=20, verbose_name='用户名', null=True, blank=True, default='碎嘴子大王')
    account = models.CharField(max_length=20, verbose_name='账号', unique=True)
    password = models.CharField(max_length=20, verbose_name='密码')
    avatar = models.FileField(upload_to='user/avatar/', verbose_name='头像', null=True, blank=True, default='user/avatar/default.jpg')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    user_id = models.CharField(primary_key=True, verbose_name='用户ID',unique=True, max_length=150)
    
    def save(self, *args, **kwargs):
        # 只在创建新用户时生成 user_id
        if not self.user_id:
            self.user_id = str(uuid.uuid4())

        # 密码长度至少6位到12位
        if len(self.password) < 6 or len(self.password) > 12:
            raise ValueError("密码长度至少6位到12位")
        # 密码只能包含字母、数字、@符号和下划线
        if not re.match(r'^[a-zA-Z0-9@_]+$', self.password):
            raise ValueError("密码只能包含字母、数字、@符号和下划线")
        # 账号只能包含数字，并且不能超过11位
        if not re.match(r'^[0-9]+$', self.account) or len(self.account) > 11:
            raise ValueError("账号只能包含数字，并且不能超过11位")
        super().save(*args, **kwargs)

    class Meta:
        db_table = 'users'
        verbose_name = '用户'
        verbose_name_plural = '用户'

# 超级管理员
class SuperAdmin(models.Model):
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE, to_field='user_id')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)

    def save(self, *args, **kwargs):
        # 一个用户只能有一个超级管理员
        if SuperAdmin.objects.filter(user_id=self.user_id).exists():
            raise ValueError("一个用户只能有一个超级管理员")
        super().save(*args, **kwargs)



# 帖子分类
class PostCategory(models.Model):
    name = models.CharField(max_length=20, verbose_name='分类名称', unique=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    

    class Meta:
        db_table = 'post_category'
        verbose_name = '帖子分类'
        verbose_name_plural = '帖子分类'



class Post(models.Model):
    # 帖子的标题，使用 CharField 存储字符串，最大长度为 200
    title = models.CharField(max_length=200)
    # 帖子的内容，使用 TextField 存储较长的文本
    content = models.TextField()
    # 帖子的作者，使用外键关联到 Django 的 User 模型，当用户被删除时，与之关联的帖子也会被删除（on_delete=models.CASCADE）
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE, to_field='user_id')
    # 帖子的创建时间，使用 DateTimeField 存储日期和时间，auto_now_add=True 表示在创建对象时自动添加当前时间
    created_at = models.DateTimeField(auto_now_add=True)
    # 帖子的更新时间，使用 DateTimeField 存储日期和时间，auto_now=True 表示在每次保存对象时更新时间
    updated_at = models.DateTimeField(auto_now=True)
    # 帖子的点赞数
    likes = models.IntegerField(default=0)
    # 帖子是否被置顶
    is_pinned = models.BooleanField(default=False)

    # 帖子封面
    cover = models.FileField(upload_to='post/cover/', verbose_name='帖子封面', null=True, blank=True)
    
    category = models.ForeignKey(PostCategory, on_delete=models.CASCADE, to_field='id')


# 帖子媒体资源
class PostMedia(models.Model):
    # 媒体资源类型
    media_type_choices = [
        (1, '图片'),
        (2, '视频'),
        (3, '音频'),
    ]
    media_type = models.IntegerField(choices=media_type_choices, verbose_name='媒体资源类型')
    post_id = models.ForeignKey(Post, on_delete=models.CASCADE, to_field='id')
    media_url = models.FileField(upload_to='post/media/', verbose_name='媒体资源')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    # 顺序
    order = models.IntegerField(verbose_name='顺序', default=0, null=True, blank=True)
    # 每次创建帖子媒体资源时，自动增加顺序
    def save(self, *args, **kwargs):
        if not self.order:
            self.order = PostMedia.objects.filter(post_id=self.post_id).count() + 1
        super().save(*args, **kwargs)


    
# 点赞或者收藏帖子，一个用户只能对一个帖子进行一次点赞或者收藏
class PostLike(models.Model):
    # 用户id
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE, to_field='user_id')
    # 帖子id
    post_id = models.ForeignKey(Post, on_delete=models.CASCADE, to_field='id')
    # 是否点赞
    is_like = models.BooleanField(default=False)
    # 是否收藏
    is_collect = models.BooleanField(default=False)

    class Meta:
        db_table = 'post_like'
        verbose_name = '帖子点赞'
        verbose_name_plural = '帖子点赞'

# 帖子评论
class PostComment(models.Model):
    post_id = models.ForeignKey(Post, on_delete=models.CASCADE, to_field='id')
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE, to_field='user_id')
    content = models.TextField(verbose_name='评论内容')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    class Meta:
        db_table = 'post_comment'
        verbose_name = '帖子评论'
        verbose_name_plural = '帖子评论'
    
    # 防注入
    def save(self, *args, **kwargs):
        # 评论内容不能为空
        if not self.content:
            raise ValueError("评论内容不能为空")
        # 评论内容不能超过1000字
        if len(self.content) > 1000:
            raise ValueError("评论内容不能超过1000字")
   
        # 评论内容不能有尖括号
        if re.search(r'[<>]', self.content):
            raise ValueError("评论内容不能包含尖括号")
        super().save(*args, **kwargs)

# 系统公告栏
class SystemAnnouncement(models.Model):
    title = models.CharField(max_length=200, verbose_name='公告标题')
    content = models.TextField(verbose_name='公告内容')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE, to_field='user_id')
    # 是否置顶
    is_pinned = models.BooleanField(default=False)
    class Meta:
        db_table = 'system_announcement'
        verbose_name = '系统公告'
        verbose_name_plural = '系统公告'
    # 只有超级管理员可以添加媒体资源
    def save(self, *args, **kwargs):
        super_admin = SuperAdmin.objects.filter(user_id=self.user_id).first()
        if not super_admin:
            raise ValueError("您不是超级管理员")
        super().save(*args, **kwargs)


# 系统公告栏的媒体资源
class SystemAnnouncementMedia(models.Model):
    system_announcement_id = models.ForeignKey(SystemAnnouncement, on_delete=models.CASCADE, to_field='id')
    media_url = models.FileField(upload_to='system_announcement/media/', verbose_name='媒体资源')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    # 类型
    media_type_choices = [
        (1, '图片'),
        (2, '视频'),
        (3, '音频'),
    ]
    media_type = models.IntegerField(choices=media_type_choices, verbose_name='媒体资源类型')   
    class Meta:
        db_table = 'system_announcement_media'
        verbose_name = '系统公告媒体资源'
        verbose_name_plural = '系统公告媒体资源'



# 系统版本
class SystemVersion(models.Model):
    version = models.CharField(max_length=20, verbose_name='版本号', unique=True)
    # 下载地址
    download_url = models.URLField(verbose_name='下载地址', max_length=300)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    class Meta:
        db_table = 'system_version'
        verbose_name = '系统版本'
        verbose_name_plural = '系统版本'

# 系统版本更新
class SystemVersionUpdate(models.Model):
    system_version_id = models.ForeignKey(SystemVersion, on_delete=models.CASCADE, to_field='id')
    # 更新类型
    update_type_choices = [
        (1, '新增'),
        (2, '修改'),
        (3, '删除'),
    ]
    update_type = models.IntegerField(choices=update_type_choices, verbose_name='更新类型')
    # 更新内容
    update_content = models.TextField(verbose_name='更新内容')
  
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    class Meta:
        db_table = 'system_version_update'
        verbose_name = '系统版本更新'
        verbose_name_plural = '系统版本更新'


# 通道分类
class PassageCategory(models.Model):
    name = models.CharField(max_length=200, verbose_name='通道分类名称', unique=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    # 是否显示
    is_show = models.BooleanField(default=True)
    class Meta:
        db_table = 'passage_category'
        verbose_name = '通道分类'
        verbose_name_plural = '通道分类'


# 通道
class Passage(models.Model):
    name = models.CharField(max_length=6, verbose_name='通道名称')
    url = models.URLField(verbose_name='通道地址', max_length=300)
    icon = models.FileField(upload_to='passage/image/', verbose_name='通道封面', null=True, blank=True)
    description = models.TextField(verbose_name='通道描述', null=True, blank=True, default='')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    category = models.ForeignKey(PassageCategory, on_delete=models.CASCADE, to_field='id')


# 系统通知(用户通知)
class SystemNotification(models.Model):
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE, to_field='user_id')
    content = models.TextField(verbose_name='通知内容')
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    # 是否已读
    is_read = models.BooleanField(default=False)
    class Meta:
        db_table = 'system_notification'
        verbose_name = '系统通知'
        verbose_name_plural = '系统通知'


# 联系我们
class ContactUs(models.Model):
    # 联系方式
    contact_way = models.CharField(max_length=20, verbose_name='联系方式')
    # 联系方式内容
    contact_content = models.CharField(max_length=20, verbose_name='联系方式内容')
    # 联系方式二维码
    contact_qr = models.FileField(upload_to='contact/qr/', verbose_name='联系方式二维码', null=True, blank=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True)
    class Meta:
        db_table = 'contact_us'
        verbose_name = '联系我们'
        verbose_name_plural = '联系我们'
